package e1

import (
	`fmt`
	`strconv`
	`strings`

	`tools/src/utils`
)

func ParseContent(content *string) (result []*ExperimentData) {
	rows := strings.Split(*content, "\n")
	for end := 0; end < len(rows); {
		if strings.HasPrefix(rows[end], "----") {
			var t *ExperimentData
			t, end = parseOneExperiment(rows, end+1)

			result = append(result, t)
		} else {
			end++
		}
	}
	return
}

func parseOneExperiment(rows []string, start int) (*ExperimentData, int) {
	end := start
	data := &ExperimentData{}
	var err error
	for end < len(rows) {
		switch {
		case strings.HasPrefix(rows[end], "----"):
			return data, end - 1
		case strings.EqualFold(rows[end], "--send-data--"):
			data.SendCount, err = strconv.Atoi(rows[end+1])
			if err != nil {
				panic(fmt.Sprintf("get send count fail, error: %s", err.Error()))
			}
			end += 2
		case strings.EqualFold(rows[end], "--cp-stats--"):
			data.CpMemorySize, end = parseMemorySize(rows, end+1)
		case strings.EqualFold(rows[end], "--cp-time-checkpoint--"):
			data.CpCheckPointUserTime, data.CpCheckPointSysTime, end = parseTimeMark(rows, end+1)
		case strings.EqualFold(rows[end], "--cp-time-restore--"):
			data.CpRestoreUserTime, data.CpRestoreSysTime, end = parseTimeMark(rows, end+1)
		case strings.EqualFold(rows[end], "--cp-tar-size--"):
			data.CpTarSize, end = parseTarSize(rows, end+1)

		case strings.EqualFold(rows[end], "--pcp-stats--"):
			data.PcpMemorySize, end = parseMemorySize(rows, end+1)
		case strings.EqualFold(rows[end], "--pcp-time-pre-checkpoint--"):
			data.PcpPreCheckPointUserTime, data.PcpPreCheckPointSysTime, end = parseTimeMark(rows, end+1)
		case strings.EqualFold(rows[end], "--pcp-time-checkpoint--"):
			data.PcpCheckPointUserTime, data.PcpCheckPointSysTime, end = parseTimeMark(rows, end+1)
		case strings.EqualFold(rows[end], "--pcp-time-restore--"):
			data.PcpRestoreUserTime, data.PcpRestoreSysTime, end = parseTimeMark(rows, end+1)
		case strings.EqualFold(rows[end], "--pcp-pre-tar-size--"):
			data.PcpPreTarSize, end = parseTarSize(rows, end+1)
		case strings.EqualFold(rows[end], "--pcp-tar-size--"):
			data.PcpTarSize, end = parseTarSize(rows, end+1)
		default:
			end++
		}
	}
	return data, end - 1
}

func parseMemorySize(rows []string, start int) (int, int) {
	/*  [
	 {
	  "id": "76ac89f1199b",
	  "name": "objective_villani",
	  "cpu_percent": "9.64%",
	  "mem_usage": "2.585MB / 8.162GB",
	  "mem_percent": "0.03%",
	  "net_io": "700B / 2.333kB",
	  "block_io": "-- / --",
	  "pids": "4"
	 }
	]
	*/
	end := start
	for end++; end < len(rows); end++ {
		if strings.Contains(rows[end], "mem_usage") {
			row := rows[end]                        //"mem_usage": "2.585MB / 8.162GB",
			row = strings.Split(row, ":")[1]        // "2.585MB / 8.162GB",
			row = strings.ReplaceAll(row, "\"", "") // 2.585MB / 8.162GB,
			row = strings.Split(row, "/")[0]        // 2.585MB
			memorySize, err := utils.ToKB(row)
			if err != nil {
				panic(err)
			}
			return memorySize, end + 1
		}
	}
	panic("when parse memory, not found mem_usage")
}

func parseTimeMark(rows []string, start int) (int, int, int) {
	/*
		76ac89f1199b31cdb98349077d0111f4cac36a895a42f87ae72417fa70c86630
		...

		real	0m0.631s
		user	0m0.083s
		sys	0m0.228s
	*/
	end := start
	var user, sys int64 = 0, 0
	var err error
	for end++; end < len(rows); end++ {
		if strings.HasPrefix(rows[end], "user") {
			//user	0m0.083s
			row := rows[end][4:]
			user, err = utils.ToMS(row)
		}
		if strings.HasPrefix(rows[end], "sys") {
			//sys	0m0.228s
			row := rows[end][3:]
			sys, err = utils.ToMS(row)
		}

		if err != nil {
			panic(err)
		}

		if user != 0 && sys != 0 {
			return int(user), int(sys), end + 1
		}
	}

	panic("when parse time mark, not found user and sys")
}

func parseTarSize(rows []string, start int) (int, int) {
	/*
		total 152
		-rw------- 1 root root 154614 Dec 19 17:21 redis-checkpoint.tar.gz
	*/
	end := start
	for ; end < len(rows); end++ {
		if strings.HasPrefix(rows[end], "total") {
			continue
		}

		if strings.HasSuffix(rows[end], "tar.gz") && strings.HasPrefix(rows[end], "-rw") {
			//-rw------- 1 root root 154614 Dec 19 17:21 redis-checkpoint.tar.gz
			row := rows[end]
			size, err := strconv.Atoi(strings.Split(row, " ")[4])
			if err != nil {
				panic(err)
			}
			return size, end + 1
		} else {
			break
		}
	}
	panic("when parse tar size, not found")
}
